package com.team.star.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.team.star.dao.RoleDAO;
import com.team.star.entity.dto.RoleDTO;
import com.team.star.entity.pojo.Role;
import com.team.star.entity.vo.RoleVO;
import com.team.star.exception.ServiceExceptionHandler;
import com.team.star.service.RoleService;
import com.team.star.utils.ResponseCode;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.beans.PropertyDescriptor;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
@Transactional
public class RoleServiceImpl implements RoleService {
    private final RoleDAO roleDAO;

    @Autowired
    public RoleServiceImpl(RoleDAO roleDAO) {
        this.roleDAO = roleDAO;
    }

    /**
     * 获取角色列表
     *
     * @return
     */
    @Override
    public List<RoleDTO> getRoleList() {
        List<Role> roleList = roleDAO.selectList(null);
        if (roleList.isEmpty()) {
            throw new ServiceExceptionHandler(ResponseCode.REQUEST_NOTE_NOT_EXIST);
        }
        return roleList.stream()
                .map(role -> {
                    RoleDTO roleDTO = new RoleDTO();
                    BeanUtils.copyProperties(role, roleDTO);
                    return roleDTO;
                }).collect(Collectors.toList());
    }

    /**
     * 根据角色名获取角色信息
     *
     * @param roleName
     * @return
     */
    @Override
    public RoleDTO getRoleByName(String roleName) {
        Role role = roleDAO.selectOne(new QueryWrapper<Role>().eq("rolename", roleName));
        if (Objects.isNull(role)) {
            throw new ServiceExceptionHandler(ResponseCode.REQUEST_NOTE_NOT_EXIST);
        }
        RoleDTO roleDTO = new RoleDTO();
        BeanUtils.copyProperties(role, roleDTO);
        return roleDTO;
    }

    /**
     * 添加角色
     *
     * @param roleVO
     */
    @Override
    public void addRole(RoleVO roleVO) {
        if (Objects.isNull(roleVO)) {
            throw new ServiceExceptionHandler(ResponseCode.ROLE_INFORMATION_IS_EMPTY);
        }
        Role roleByName = roleDAO.selectOne(new QueryWrapper<Role>()
                .eq("rolename", roleVO.getRolename())
        );
        if (Objects.nonNull(roleByName)) {
            throw new ServiceExceptionHandler(ResponseCode.REQUEST_NOTE_EXIST);
        }
        Role role = new Role();
        BeanUtils.copyProperties(roleVO, role);
        try {
            roleDAO.insert(role);
        } catch (Exception e) {
            throw new ServiceExceptionHandler(ResponseCode.ERROR);
        }
    }

    /**
     * 删除角色
     *
     * @param roleName
     */
    @Override
    public void deleteRole(String roleName) {
        if (roleName == null) {
            throw new ServiceExceptionHandler(ResponseCode.PARAM_ERROR);
        }
        QueryWrapper<Role> eq = new QueryWrapper<Role>().eq("rolename", roleName);
        Role role = roleDAO.selectOne(eq);
        if (Objects.isNull(role)) {
            throw new ServiceExceptionHandler(ResponseCode.REQUEST_NOTE_NOT_EXIST);
        }
        roleDAO.deleteById(role.getRoleId());
    }

    /**
     * 更新角色信息
     *
     * @param roleVO
     */
    @Override
    public void updateRole(RoleVO roleVO) {
        if (Objects.isNull(roleVO) || Objects.isNull(roleVO.getRolename())) {
            throw new ServiceExceptionHandler(ResponseCode.REQUEST_NOTE_NOT_EXIST);
        }
        Role existingRole = roleDAO.selectOne(new QueryWrapper<Role>().eq("rolename", roleVO.getRolename()));
        if (Objects.isNull(existingRole)) {
            throw new ServiceExceptionHandler(ResponseCode.REQUEST_NOTE_NOT_EXIST);
        }
        Role updatedRole = new Role();
        BeanUtils.copyProperties(existingRole, updatedRole);
        copyDifferentProperties(roleVO, updatedRole, existingRole);

        roleDAO.updateById(updatedRole);
    }

    /**
     * 比较 source 和 target 中的属性
     * 仅复制不同的字段
     *
     * @param source
     * @param target
     * @param existing
     */
    private void copyDifferentProperties(RoleVO source, Role target, Role existing) {
        //获取属性值
        BeanWrapper srcWrapper = new BeanWrapperImpl(source);
        BeanWrapper existingWrapper = new BeanWrapperImpl(existing);
        BeanWrapper targetWrapper = new BeanWrapperImpl(target);

        for (PropertyDescriptor pd : srcWrapper.getPropertyDescriptors()) {
            String propertyName = pd.getName();
            // 忽略 class 属性
            if ("class".equals(propertyName)) continue;

            Object srcValue = srcWrapper.getPropertyValue(propertyName);
            Object existingValue = existingWrapper.getPropertyValue(propertyName);

            // 如果 source 中字段不为空，且值与 existing 不同，则更新到 target
            if (srcValue != null && !Objects.equals(srcValue, existingValue)) {
                targetWrapper.setPropertyValue(propertyName, srcValue);
            }
        }
    }

}
